package matrix;

import org.apache.log4j.Logger;

/**
 * Created with IntelliJ IDEA.
 * User: aleks_000
 * Date: 29.09.13
 * Time: 17:07
 * To change this template use File | Settings | File Templates.
 */
public class SimpleMatrixMultiplier implements MatrixMultiplier {

    private static final Logger LOGGER = Logger.getLogger(SimpleMatrixMultiplier.class);

    private static void multiply(Matrix first, Matrix second, Matrix result) throws MatrixIncompatibleException{
        if (first.getColumnCount() != second.getRowCount()) {
            LOGGER.warn("Incompatible matrix sizes. Might MatrixIncompatibleException occurs");
            throw new MatrixIncompatibleException();
        }
        if (result.getColumnCount() != second.getColumnCount()) {
            LOGGER.warn("Result matrix has incorrect column count");
            throw new IllegalArgumentException();
        }
        if (result.getRowCount() != first.getRowCount()){
            LOGGER.warn("Result matrix has an incorrect row count");
            throw new IllegalArgumentException();
        }

        for (int row = 0; row < first.getRowCount(); ++row) {
            for (int column = 0; column < second.getColumnCount(); ++column) {
                double value = 0.0;
                for (int k = 0; k < first.getColumnCount(); ++k) {
                    value += first.getValue(row, k) * second.getValue(k, column);
                }
                result.setValue(row, column, value);
            }
        }
    }

    @Override
    public <T extends Matrix> T multiply(Matrix first, Matrix second, MatrixFactory<T> matrixFactory)
            throws MatrixIncompatibleException {
        if (matrixFactory == null) {
            throw new NullPointerException("matrixFactory");
        }
        T result = matrixFactory.create(first.getRowCount(), second.getColumnCount());
        multiply(first, second, result);
        return result;
    }
}
